/**
 * 动画引擎核心
 * 高性能的关键帧插值和动画计算系统
 */

// 缓动函数类型
export type EasingFunction = (t: number) => number

// 缓动函数库
export const easingFunctions: Record<string, EasingFunction> = {
  linear: (t: number) => t,
  
  'ease-in': (t: number) => t * t,
  'ease-out': (t: number) => 1 - (1 - t) * (1 - t),
  'ease-in-out': (t: number) => t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2,
  
  'ease-in-cubic': (t: number) => t * t * t,
  'ease-out-cubic': (t: number) => 1 - Math.pow(1 - t, 3),
  'ease-in-out-cubic': (t: number) => t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2,
  
  'ease-in-quart': (t: number) => t * t * t * t,
  'ease-out-quart': (t: number) => 1 - Math.pow(1 - t, 4),
  'ease-in-out-quart': (t: number) => t < 0.5 ? 8 * t * t * t * t : 1 - Math.pow(-2 * t + 2, 4) / 2,
  
  'ease-in-back': (t: number) => {
    const c1 = 1.70158
    const c3 = c1 + 1
    return c3 * t * t * t - c1 * t * t
  },
  'ease-out-back': (t: number) => {
    const c1 = 1.70158
    const c3 = c1 + 1
    return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2)
  },
  
  bounce: (t: number) => {
    const n1 = 7.5625
    const d1 = 2.75
    
    if (t < 1 / d1) {
      return n1 * t * t
    } else if (t < 2 / d1) {
      return n1 * (t -= 1.5 / d1) * t + 0.75
    } else if (t < 2.5 / d1) {
      return n1 * (t -= 2.25 / d1) * t + 0.9375
    } else {
      return n1 * (t -= 2.625 / d1) * t + 0.984375
    }
  }
}

// 插值器接口
export interface Interpolator<T> {
  interpolate(from: T, to: T, progress: number): T
}

// 数值插值器
export class NumberInterpolator implements Interpolator<number> {
  interpolate(from: number, to: number, progress: number): number {
    return from + (to - from) * progress
  }
}

// 位置插值器
export class PositionInterpolator implements Interpolator<{x: number, y: number}> {
  interpolate(from: {x: number, y: number}, to: {x: number, y: number}, progress: number): {x: number, y: number} {
    return {
      x: from.x + (to.x - from.x) * progress,
      y: from.y + (to.y - from.y) * progress
    }
  }
}

// 颜色插值器
export class ColorInterpolator implements Interpolator<string> {
  interpolate(from: string, to: string, progress: number): string {
    // 简单的RGB颜色插值
    const fromRgb = this.parseColor(from)
    const toRgb = this.parseColor(to)
    
    if (!fromRgb || !toRgb) return from
    
    const r = Math.round(fromRgb.r + (toRgb.r - fromRgb.r) * progress)
    const g = Math.round(fromRgb.g + (toRgb.g - fromRgb.g) * progress)
    const b = Math.round(fromRgb.b + (toRgb.b - fromRgb.b) * progress)
    
    return `rgb(${r}, ${g}, ${b})`
  }
  
  private parseColor(color: string): {r: number, g: number, b: number} | null {
    // 简单的颜色解析，支持 #hex 和 rgb() 格式
    if (color.startsWith('#')) {
      const hex = color.slice(1)
      if (hex.length === 6) {
        return {
          r: parseInt(hex.slice(0, 2), 16),
          g: parseInt(hex.slice(2, 4), 16),
          b: parseInt(hex.slice(4, 6), 16)
        }
      }
    }
    
    const rgbMatch = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/)
    if (rgbMatch) {
      return {
        r: parseInt(rgbMatch[1]),
        g: parseInt(rgbMatch[2]),
        b: parseInt(rgbMatch[3])
      }
    }
    
    return null
  }
}

// 关键帧接口
export interface Keyframe {
  time: number
  value: any
  easing?: string
}

// 动画轨道接口
export interface AnimationTrack {
  id: string
  property: string
  keyframes: Keyframe[]
}

// 动画引擎类
export class AnimationEngine {
  private interpolators = new Map<string, Interpolator<any>>()
  private performanceStats = {
    lastFrameTime: 0,
    frameCount: 0,
    averageFrameTime: 0
  }
  
  constructor() {
    // 注册默认插值器
    this.registerInterpolator('number', new NumberInterpolator())
    this.registerInterpolator('position', new PositionInterpolator())
    this.registerInterpolator('color', new ColorInterpolator())
  }
  
  registerInterpolator<T>(type: string, interpolator: Interpolator<T>) {
    this.interpolators.set(type, interpolator)
  }
  
  // 计算指定时间的属性值
  calculateValueAtTime(track: AnimationTrack, time: number): any {
    const keyframes = track.keyframes.sort((a, b) => a.time - b.time)
    
    if (keyframes.length === 0) return null
    if (keyframes.length === 1) return keyframes[0].value
    
    // 如果时间在第一个关键帧之前
    if (time <= keyframes[0].time) {
      return keyframes[0].value
    }
    
    // 如果时间在最后一个关键帧之后
    if (time >= keyframes[keyframes.length - 1].time) {
      return keyframes[keyframes.length - 1].value
    }
    
    // 找到当前时间所在的关键帧区间
    for (let i = 0; i < keyframes.length - 1; i++) {
      const currentKeyframe = keyframes[i]
      const nextKeyframe = keyframes[i + 1]
      
      if (time >= currentKeyframe.time && time <= nextKeyframe.time) {
        return this.interpolateBetweenKeyframes(currentKeyframe, nextKeyframe, time)
      }
    }
    
    return keyframes[keyframes.length - 1].value
  }
  
  // 在两个关键帧之间插值
  private interpolateBetweenKeyframes(from: Keyframe, to: Keyframe, time: number): any {
    const duration = to.time - from.time
    if (duration === 0) return from.value
    
    const progress = (time - from.time) / duration
    const easingFunction = easingFunctions[to.easing || 'linear']
    const easedProgress = easingFunction(progress)
    
    // 根据值类型选择插值器
    const valueType = this.detectValueType(from.value)
    const interpolator = this.interpolators.get(valueType)
    
    if (interpolator) {
      return interpolator.interpolate(from.value, to.value, easedProgress)
    }
    
    // 默认返回起始值
    return from.value
  }
  
  // 检测值类型
  private detectValueType(value: any): string {
    if (typeof value === 'number') return 'number'
    if (value && typeof value === 'object' && 'x' in value && 'y' in value) return 'position'
    if (typeof value === 'string' && (value.startsWith('#') || value.startsWith('rgb'))) return 'color'
    return 'number' // 默认
  }
  
  // 计算图层在指定时间的所有属性
  calculateLayerPropertiesAtTime(layer: any, tracks: any[], time: number): Record<string, any> {
    const startTime = performance.now()
    
    const properties: Record<string, any> = {}
    
    // 找到属于该图层的所有轨道
    const layerTracks = tracks.filter(track => track.layerId === layer.id)
    
    for (const track of layerTracks) {
      if (track.keyframes && track.keyframes.length > 0) {
        // 根据轨道类型确定属性名
        const propertyName = this.getPropertyNameFromTrackType(track.type)
        if (propertyName) {
          const animatedValue = this.calculateValueAtTime({
            id: track.id,
            property: propertyName,
            keyframes: track.keyframes
          }, time)
          
          if (animatedValue !== null) {
            properties[propertyName] = animatedValue
          }
        }
      }
    }
    
    // 更新性能统计
    const frameTime = performance.now() - startTime
    this.updatePerformanceStats(frameTime)
    
    return properties
  }
  
  // 从轨道类型获取属性名
  private getPropertyNameFromTrackType(trackType: string): string | null {
    const typeMap: Record<string, string> = {
      'transform': 'transform',
      'position': 'position',
      'scale': 'scale',
      'rotation': 'rotation',
      'opacity': 'opacity'
    }
    
    return typeMap[trackType] || null
  }
  
  // 更新性能统计
  private updatePerformanceStats(frameTime: number) {
    this.performanceStats.frameCount++
    this.performanceStats.lastFrameTime = frameTime
    
    // 计算平均帧时间（使用滑动平均）
    const alpha = 0.1
    this.performanceStats.averageFrameTime = 
      this.performanceStats.averageFrameTime * (1 - alpha) + frameTime * alpha
  }
  
  // 获取性能统计
  getPerformanceStats() {
    return {
      ...this.performanceStats,
      fps: this.performanceStats.averageFrameTime > 0 ? 1000 / this.performanceStats.averageFrameTime : 0
    }
  }
  
  // 优化关键帧（移除冗余的关键帧）
  optimizeKeyframes(track: AnimationTrack, tolerance = 0.001): AnimationTrack {
    if (track.keyframes.length <= 2) return track
    
    const optimizedKeyframes: Keyframe[] = [track.keyframes[0]]
    
    for (let i = 1; i < track.keyframes.length - 1; i++) {
      const prev = track.keyframes[i - 1]
      const current = track.keyframes[i]
      const next = track.keyframes[i + 1]
      
      // 计算如果移除当前关键帧，在其时间点的插值结果
      const interpolatedValue = this.interpolateBetweenKeyframes(prev, next, current.time)
      
      // 如果插值结果与实际值差异较大，保留该关键帧
      if (this.calculateValueDifference(current.value, interpolatedValue) > tolerance) {
        optimizedKeyframes.push(current)
      }
    }
    
    // 始终保留最后一个关键帧
    optimizedKeyframes.push(track.keyframes[track.keyframes.length - 1])
    
    return {
      ...track,
      keyframes: optimizedKeyframes
    }
  }
  
  // 计算值差异
  private calculateValueDifference(value1: any, value2: any): number {
    if (typeof value1 === 'number' && typeof value2 === 'number') {
      return Math.abs(value1 - value2)
    }
    
    if (value1 && value2 && typeof value1 === 'object' && typeof value2 === 'object') {
      if ('x' in value1 && 'y' in value1 && 'x' in value2 && 'y' in value2) {
        return Math.sqrt(Math.pow(value1.x - value2.x, 2) + Math.pow(value1.y - value2.y, 2))
      }
    }
    
    return value1 === value2 ? 0 : 1
  }
}

// 导出单例实例
export const animationEngine = new AnimationEngine()
